﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.IO;
using Microsoft.VisualBasic.FileIO;
using System.ComponentModel;
namespace DataChannel.Web
{
    public class Txt2DataTable: IDisposable
    {
        /// <summary>
        /// txt源文件路径
        /// </summary>
        private string FileName;
       
        
        private string _sourceTableName = string.Empty;
        /// <summary>
        /// d在数据库中的源数据表名
        /// </summary>
        public string SourceTableName
        {
            get { return _sourceTableName; }
        }

        
        private DataTable _sourceDataTable = null;
        /// <summary>
        /// 数据表
        /// </summary>
        public DataTable SourceDataTable
        {
            get { return _sourceDataTable; }
        }

        private string _createTableSql = string.Empty;

        /// <summary>
        /// 返回创建源数据表的SQL命令
        /// </summary>
        public string CreateTableSql
        {
            get { return _createTableSql; }
        }

        
        private string _keyColumn = string.Empty;
        /// <summary>
        /// 关键列名，即txt文件中第一列
        /// </summary>
        public string KeyColumn
        {
            get 
            { 
                return string.Format("{0}",_keyColumn);
            }
        }



        public Txt2DataTable(string FileName, string Delimiters )
        {
            this.FileName = FileName;
            try
            {
                this._sourceTableName = GenerateTableName();
                this._sourceDataTable = this.ImportDataFromTxtFile(this.FileName, string.Format("{0}", Delimiters));
            }
            catch (Exception e)
            {
                
                throw e;
            }
        }

        private string GenerateTableName()
        {
            try
            {
                //string temName = this.FileName.Substring(this.FileName.LastIndexOf('\\') + 1);
                //temName = temName.Substring(0, temName.LastIndexOf('.') );
                //return DCDataStructs.UniqueString.Generate("DC");
            }
            catch (Exception e)
            {
                
                throw e;
            }
        }

        /// <summary>
        /// 将txt文件的数据导入到DataTable
        /// </summary>
        /// <param name="TxtFile">输入的源数据</param>
        /// <param name="Delimiters">列分隔符</param>
        /// <returns></returns>
        private DataTable ImportDataFromTxtFile(string TxtFile, string Delimiters)
        {
            using (TextFieldParser myReader = new TextFieldParser(TxtFile,Encoding.Default))
            {
                // 表示文件内容是字符分隔。
                try
                {
                    
                    myReader.TextFieldType = FieldType.Delimited;

                    // 定义文字文件的字符分隔符。
                    myReader.Delimiters = new string[] { Delimiters };

                    string[] currentRow = null;
                    DataTable resultDT = new DataTable(this._sourceTableName);
                    // 循环处理文字文件中所有数据列的所有字段。
                    while (!myReader.EndOfData)
                    {
                        currentRow = myReader.ReadFields();
                        if (currentRow != null && currentRow.Length > 0)
                        {
                            break;
                        }
                    }
                    this._keyColumn = currentRow[0];

                    string temSql = string.Empty;
                    foreach (string col in currentRow)
                    {
                        resultDT.Columns.Add(col, Type.GetType("System.String"));
                        temSql += string.Format("[{0}] varchar(5000),", col); 

                    }

                    temSql = temSql.Remove(temSql.LastIndexOf(",") );
                    

                    this._createTableSql = string.Format("if exists (select name from dbo.sysobjects where name=N'{0}')"
                                                           +"\r\n drop table [dbo].[{0}] \r\n create table [{0}]({1})",
                        this.SourceTableName,temSql);




                    currentRow = null;
                    while (!myReader.EndOfData)
                    {
                        currentRow = myReader.ReadFields();
                        if (currentRow != null && currentRow.Length > 0)
                        {
                            resultDT.Rows.Add(currentRow);
                        }
                    }
                    return resultDT;
                }
                catch (Exception ex)
                {

                    throw ex;
                }
                finally
                {
                    if (myReader != null)
                    {
                        try
                        {
                            myReader.Close();
                            myReader.Dispose();
                        }
                        catch (Exception)
                        {
                        }
                    }
                    GC.Collect();
                }
            }
        }


        // Pointer to an external unmanaged resource.
        private IntPtr handle;
        // Other managed resource this class uses.
        private Component component = new Component();
        // Track whether Dispose has been called.
        private bool disposed = false;


        #region IDisposable 成员

        public void Dispose()
        {
            Dispose(true);
            // This object will be cleaned up by the Dispose method.
            // Therefore, you should call GC.SupressFinalize to
            // take this object off the finalization queue
            // and prevent finalization code for this object
            // from executing a second time.
            GC.SuppressFinalize(this);
        }

           private void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if(!this.disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if(disposing)
                {
                    // Dispose managed resources.

                    if (this.SourceDataTable != null)
                    {
                        this.SourceDataTable.Dispose();
                        this._sourceTableName= null;

                    }
                    this._sourceTableName = null;
                    this._createTableSql = null;
                    component.Dispose();
                }

                // Call the appropriate methods to clean up
                // unmanaged resources here.
                // If disposing is false,
                // only the following code is executed.
                //CloseHandle(handle);
                //handle = IntPtr.Zero;

                // Note disposing has been done.
                disposed = true;

            }
        }

        // Use interop to call the method necessary
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        // Use C# destructor syntax for finalization code.
        // This destructor will run only if the Dispose method
        // does not get called.
        // It gives your base class the opportunity to finalize.
        // Do not provide destructors in types derived from this class.
        ~Txt2DataTable()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false) is optimal in terms of
            // readability and maintainability.
            Dispose(true);
        }

        #endregion
    }
}
